home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mm / mm-0.90 / init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  8.9 KB  |  386 lines

  1. /*
  2.  * Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  * the City of New York.  Permission is granted to any individual or
  4.  * institution to use, copy, or redistribute this software so long as it
  5.  * is not sold for profit, provided this copyright notice is retained.
  6.  */
  7.  
  8. #ifndef lint
  9. static char *rcsid = "$Header: /f/src2/encore.bin/cucca/mm/tarring-it-up/RCS/init.c,v 2.5 90/10/04 18:24:32 melissa Exp $";
  10. #endif
  11.  
  12. /*
  13.  * init.c - various initialization procedures for mm
  14.  */
  15.  
  16. #include "mm.h"
  17. #include "parse.h"
  18. #include "set.h"
  19. #include "cmds.h"
  20.  
  21. /*
  22.  * <pwd.h> has already been included, but it may not have declared getpwnam()
  23.  */
  24. struct passwd *getpwnam();
  25. /*
  26.  * Ditto for <grp.h> and getgrgid()
  27.  */
  28. struct group *getgrgid();
  29.  
  30. char *HOME, *real_personal_name;
  31. int PID;
  32. int UID;
  33. int OLD_UMASK;                /* umask at time mm started */
  34. int thisyear;
  35. extern int minutes_west;        /* see dates.c */
  36.  
  37. extern int top_level_parser();
  38. extern variable set_variables[];
  39. extern int set_variable_count;
  40.  
  41.  
  42. /*
  43.  * clear all modified flags on variables and aliases
  44.  */
  45. clear_modified()
  46. {
  47.     int i;
  48.     for (i = 0; i < set_variable_count; i++) {
  49.     set_variables[i].changed = FALSE;
  50.     }
  51.     set_variables[SET_MAIL_ALIASES].changed = TRUE; /* ??? */
  52.     for (i = 0; i < mail_aliases.count; i++)
  53.     mail_aliases.aliases[i].type = MA_SYSTEM;
  54. }
  55.  
  56.  
  57. int
  58. system_init ()
  59. {
  60.     int err;
  61.  
  62.     err = take_file (SYSINIT, top_level_parser, FALSE);
  63.     return err;
  64. }
  65.  
  66. group_init ()
  67. {
  68.     struct group *g;
  69.     struct passwd *p;
  70.     char *u;
  71.     char fname[BUFSIZ];
  72.     
  73.     u = whoami();
  74.     if (u) {
  75.     p = getpwnam(u);
  76.     if (p) {
  77.         g = getgrgid(getgid());
  78.         if (g) {
  79. #ifdef GROUP_INIT_FORMAT
  80.         sprintf (fname, GROUP_INIT_FORMAT, g->gr_name);
  81. #else
  82.         sprintf(fname,"%s/%s.ini", LIBDIR, g->gr_name);
  83. #endif
  84.         take_file(fname, top_level_parser, FALSE);
  85.         }
  86.     }
  87.     }
  88. }
  89.  
  90. int
  91. user_init ()
  92. {
  93.   buffer filename;
  94.  
  95.   struct stat filestat;
  96.   extern int read_fast_init_file();
  97.   extern int write_fast_init_file();
  98.   int set_def_parser();
  99.  
  100.   if (HOME == NULL)        /* Can't do much without a home */
  101.     return false;
  102.  
  103.   if (read_fast_init_file()) {    /* try to read it */
  104.     cmcsb._cmwrp = autowrap_column;    /* make sure this takes effect */
  105.     OLD_UMASK = umask (~(new_file_mode&04777));
  106.     if (set_variables[SET_USER_NAME].changed) { /* validate username */
  107.       struct passwd *p1;
  108.       p1 = getpwnam(user_name);
  109.       if (p1 == NULL || p1->pw_uid != getuid()) {
  110.     char *u, *whoami();
  111.     fprintf (stderr, 
  112.          "Value for user_name must have the same uid as you\n");
  113.     u = whoami();
  114.     if (u)
  115.       strcpy (user_name, u);
  116.     else
  117.       user_name[0] = '\0';
  118.       }
  119.       sethome(user_name);
  120.     }
  121.     return true;            /* worked */
  122.   }
  123.   else {        /* fast init file failed, so parse and then write it */
  124.     /* umask might not get set, and besides, we want the old mask */
  125.     OLD_UMASK = umask (~(new_file_mode&04777));
  126.     sprintf(filename, "%s/.mminit", HOME);
  127.     if (take_file (filename, set_def_parser, FALSE)) {
  128.       if ((fast_init_file == SET_YES) ||
  129.       ((fast_init_file == SET_ASK) &&
  130.        (yesno ("Make new fast init file? ", "yes"))))
  131.     return write_fast_init_file();
  132.     else
  133.       return true;        /* Don't write fast if init says not to */
  134.     }
  135.     else
  136.       return false;        /* Couldn't parse it */
  137.   }
  138. }
  139.  
  140. int
  141. user_rc ()
  142. {
  143.     buffer filename;
  144.  
  145.     if (HOME == NULL)
  146.     return false;
  147.     sprintf (filename, "%s/.mmrc", HOME);
  148.     return(take_file (filename, top_level_parser, FALSE));
  149. }
  150.  
  151. /*
  152.  * initialize:
  153.  * set up various variables we want to know about
  154.  * default some mm-variables to things we have to figure out
  155.  */
  156.  
  157. int
  158. initialize (argv)
  159. char **argv;
  160. {
  161.     char *getenv();
  162.     char *username,*whoami();
  163.     long t;
  164. #if BSD
  165.     struct timeval tv;
  166.     struct timezone tz;
  167. #endif
  168. #if SYSV
  169.     extern long timezone;
  170.     struct tm *tm;
  171. #endif
  172. #ifdef UUCP                /* add uucp extension */
  173.     char *hn;
  174.     static char *uext = ".uucp";
  175. #endif /* UUCP */
  176.     char *getlocalhostname();
  177.     char **split_args();
  178.     char *get_default_temp_dir();
  179.  
  180.     PID = getpid();
  181.     UID = getuid();
  182.  
  183.     getlocalhostname();
  184.  
  185.     username = whoami();        /* get the user name */
  186.     if (username)
  187.     strcpy (user_name, username);    /* keep it */
  188.     
  189.     sethome (user_name);        /* set global HOME */
  190.  
  191.     strcpy (temp_directory, get_default_temp_dir());
  192.  
  193.     progname = rindex (argv[0], '/');
  194.     progname = (progname == nil) ? argv[0] : ++progname;
  195.  
  196.     time (&t);                /* get current time */
  197.     thisyear = (localtime (&t))->tm_year; /* XXX note that this gets stale */
  198. #if BSD
  199.     gettimeofday(&tv, &tz);
  200.     minutes_west = tz.tz_minuteswest;
  201. #endif
  202. #if SYSV
  203.     tm = localtime(&t);
  204.     asctime(tm);
  205.     minutes_west = timezone / 60;
  206. #endif
  207.  
  208. #ifdef SPELLER
  209.     speller = split_args (SPELLER);
  210. #endif /* SPELLER */
  211.     autowrap_column = cmcsb._cmwrp;
  212. }
  213.  
  214.  
  215. /*
  216.  * GET_PERSONAL_NAME:
  217.  * Given a gecos string from a struct passwd, get the personal name,
  218.  * into malloced space.
  219.  * A typical gecos field looks something like:
  220.  * Personal Name,Office,Extension,Phone
  221.  */
  222.  
  223. char *
  224. get_personal_name (s,user)
  225. char *s;
  226. char *user;
  227. {
  228.   char *cp, *p, *index();
  229.   int quote;
  230.   int size;
  231.  
  232.   size = strlen(s) * 2 + 2 + 1;        /* worst case */
  233.   cp = (char *) malloc (size);
  234.   if ((p = index (s, ',')) != NULL)    /* find comma (should be after name) */
  235.     *p = '\0';                /* replace comma with NULL */
  236.  
  237.   for (p = s; *p; p++)
  238.       if (!(isatom (*p) || isspace (*p)))
  239.       break;
  240.  
  241.   quote = *p;                /* must quote if didn't reach end */
  242.   if (quote || (index(s,'&') != NULL)) { /* found a bad character */
  243.       p = cp;                /* point at space */
  244.       if (quote)
  245.       *p++ = '"';
  246.       while (*s) {
  247.       if (*s == '\\' || *s == '"')
  248.           *p++ = '\\';
  249.       if (*s == '&') {        /* means put in username */
  250.           *p = '\0';        /* so we can find spot after realloc */
  251.           cp = (char *) realloc(cp, size+=strlen(user));
  252.           p = cp+strlen(cp);    /* get to end again */
  253.           *p++ = (islower(user[0])) ? toupper(user[0]) : user[0];
  254.           strcpy (p,&user[1]);    /* add the rest */
  255.           p += strlen(p);
  256.           s++;            /* skip the & */
  257.       }
  258.       else                /* put in everything but & */
  259.           *p++ = *s++;
  260.       }
  261.       if (quote)
  262.       *p++ = '"';
  263.       *p = 0;
  264.   }
  265.   else
  266.       strcpy (cp, s);            /* copy personal name */
  267.   cp = (char *) realloc (cp, strlen(cp)+1); /* snug it down */
  268.   return (cp);                /* return pointer to it */
  269. }
  270.  
  271. /*
  272.  * sethome:
  273.  * set various things for the (new) user-name
  274.  */
  275. sethome (name)
  276. char *name;
  277. {
  278.     struct passwd *pswd;
  279.  
  280.     pswd = getpwnam (name);        /* try to get it */
  281.  
  282.     if (real_personal_name != NULL)
  283.     free (real_personal_name);    /* getting a new one */
  284.     if (pswd != NULL)
  285.     real_personal_name = get_personal_name (pswd->pw_gecos, name);
  286.     else {
  287.     real_personal_name = NULL;
  288.     fprintf (stderr, "Warning: can't find personal name for %s\n", name);
  289.     }
  290.  
  291.     if (((HOME = getenv ("HOME")) == NULL) || /* in environment? */
  292.     (HOME[0] == '\0')) {
  293.     if (pswd != NULL) {        /* in passwd file? */
  294.         HOME = (char *) malloc (strlen (pswd->pw_dir)+1);
  295.         strcpy (HOME, pswd->pw_dir);
  296.     }
  297.     else {
  298.         fprintf (stderr, "Warning: can't find home directory for %s\n",
  299.              name);
  300.     }
  301.     }
  302. }
  303.  
  304. /*
  305.  * This routine is used to read commands from the system and user init files
  306.  *
  307.  * The argument specifies the name of the file to open.
  308.  */
  309.  
  310. int
  311. take_file (s, take_parser, echo)
  312. char *s;
  313. int (*take_parser)();
  314. int echo;
  315. {
  316.     int err, noecho, saved_flag;
  317.     FILE *fd;
  318.  
  319.     fd = fopen (s, "r");
  320.     if (fd == NULL)
  321.     return false;
  322.  
  323.     saved_flag = cmcsb._cmflg;
  324.     cmcsb._cmflg &= ~CM_ITTY;            /* non-interactive */
  325.     stack_input (fd);
  326.     if (!echo)
  327.     cmcsb._cmoj = (FILE *) NULL;    /* pop_input will restore this */
  328.     noecho = cmcsb._cmflg & CM_NEC;
  329.     cmecho(echo);
  330.     err = take_parser ();
  331.     if (cmcsb._cmerr == CMxEOF)
  332.     cmcsb._cmerr = CMxOK;
  333.     else
  334.     fprintf (stderr, "%s: unexpected error in %s\n",
  335.          progname, (s == nil) ? "input file" : s);
  336.     pop_input ();
  337.     cmcsb._cmcol = 0;            /* XXX bald assumption */
  338.     cmecho (noecho ? false : true);
  339.     cmcsb._cmflg = (cmcsb._cmflg & ~CM_ITTY) | (saved_flag & CM_ITTY);
  340.     return true;            /* propagate error */
  341. }
  342.  
  343. /*
  344.  * set_def_parser:
  345.  * parse "set" and "define" commands (from .mminit file)
  346.  */
  347. int
  348. set_def_parser ()
  349. {
  350.     static keywrd set_def_keys[] = {
  351.     { "set", 0, (keyval) CMD_SET },    /* "set" more common, put first */
  352.     { "define", 0, (keyval) CMD_DEFINE },
  353.     };
  354.     static keytab set_def_keytab = 
  355.         { sizeof (set_def_keys) / sizeof (keywrd), set_def_keys };
  356.     static fdb set_def_fdb = 
  357.         { _CMKEY, 0, nil, (pdat) &set_def_keytab, "command, " };
  358.  
  359.     cmcsb._cmerr = CMxOK;        /* assume no error */
  360.     while (true) {
  361.     if (cmseteof ())
  362.         return CMxEOF;
  363.     cmseter ();            /* errors return here */
  364.  
  365.     prompt (top_level_prompt);    /* in case someone's watching */
  366.     cmsetrp ();            /* reparse comes back here */
  367.     parse (&set_def_fdb, &pv, &used); /* parse set or define */
  368.     (void) (*mm_cmds[pv._pvkey]) (pv._pvkey); /* same routines */
  369.     }
  370. }
  371.  
  372.  
  373. /*
  374.  * get default for temp_directory variable.  Used in initialization, and
  375.  * when the user has unset the variable.
  376.  */
  377.  
  378. char *
  379. get_default_temp_dir()
  380. {
  381.     if (HOME != NULL)
  382.     return(HOME);
  383.     else
  384.     return ("/tmp");
  385. }
  386.